package com.wanaofu.dao;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;

import org.hibernate.cfg.beanvalidation.GroupsPerOperation;
import org.springframework.stereotype.Repository;

import com.wanaofu.model.AbstractBaseEntity;

@Repository 
public class UniversalDAO extends AbstractBaseDAO {

	@Resource
	private Validator validator;
	
	 /** 
     *  
     * @param o 保存实体对象 
     * @return 主键 
     */  	
    public Serializable save(AbstractBaseEntity o) { 
    	validate(o,GroupsPerOperation.Operation.INSERT);
        return this.getSession().save(o);  
    }  
//    /** 
//     * 新增或者更新 
//     *  
//     * @param o 
//     */  
//    public void saveOrUpdate(Object o) {  
//    	validate(o,GroupsPerOperation.Operation.INSERT);
//        this.getSession().saveOrUpdate(o);  
//    }  
  
    /** 
     * 更新 
     *  
     * @param o 
     */  
    public void update(Object o) {  
    	validate(o,GroupsPerOperation.Operation.UPDATE);
        this.getSession().update(o);  
    }  
    /** 
     * 更新 
     *  
     * @param o 
     */  
    public void delete(Object o) {  
        this.getSession().delete(o);  
    }  
  
    /** 
     * 删除 
     *  
     * @param clazz 
     * @param id 
     */  
    public void delete(Class<?> clazz, Serializable id) {  
        this.getSession().delete(this.get(clazz, id));  
    }  
  
    /** 
     * 逐个删除，保证缓存与数据库的统一 
     *  
     * @param ids 主键值， 
     * @return 
     */     
    public int deleteAll(Class<?> clazz, Serializable... ids) {  
        for (Serializable id : ids) {  
            delete(clazz, id);  
        }  
        return ids.length;  
    } 

	private <T> void validate(T object, GroupsPerOperation.Operation operation) {
		if (object == null) {
			return;
		}
//        System.out.println("======================================================================");
		final Set<ConstraintViolation<T>> constraintViolations = validator
				.validate(object);
		if (constraintViolations.size() > 0) {
			Set<ConstraintViolation<?>> propagatedViolations = new HashSet<ConstraintViolation<?>>(
					constraintViolations.size());
			Set<String> classNames = new HashSet<String>();
			for (ConstraintViolation<?> violation : constraintViolations) {

				propagatedViolations.add(violation);
				classNames.add(violation.getLeafBean().getClass().getName());
			}

			StringBuilder builder = new StringBuilder();
			builder.append("Validation failed for classes ");
			builder.append(classNames);
			builder.append(" during ");
			builder.append(operation.getName());
			builder.append(" time for groups ");
			builder.append("\nList of constraint violations:[\n");
			for (ConstraintViolation<?> violation : constraintViolations) {
				builder.append("\t").append(violation.toString()).append("\n");
			}
			builder.append("]");
//			throw new RuntimeException();
			throw new ConstraintViolationException(builder.toString(),
					propagatedViolations);
		}

	} 
}
